package vn.edu.hut.soict.translate.search;

import vn.edu.hut.soict.translate.utils.SemanticDistance;
import vn.edu.hut.soict.translate.wordgraph.Word;

public class Record {
	public static double MIN_COST_OF_S_RECORD = 0.05;

	private Operator operator;
	private Word graphWord;
	private Word inputWord;
	private double cost;
	
	private Record() {
		
	}

	public Record(Operator operator, Word string) {
		this.operator = operator;
		switch (operator) {
			case EXACT_MATCH:
				graphWord = string;
				inputWord = string;
				break;
			case INSERTION:
				inputWord = string;
				break;
			case DELETION:
				graphWord = string;
				break;
			default:
				throw new IllegalArgumentException("Invalid type of operator.");
		}
		cost = calculateCost();
	}

	public Record(Operator operator, Word graphWord, Word inputWord) {
		if (operator == Operator.SUBSTITUTION) {
			this.operator = operator;
			this.graphWord = graphWord;
			this.inputWord = inputWord;
		}
		else {
			throw new IllegalArgumentException("Invalid type of operator.");
		}
		cost = calculateCost();
	}

	private double calculateCost() {
		switch (operator) {
			case EXACT_MATCH:
				return 0;
			case INSERTION:
			case DELETION:
				return 1;
			case SUBSTITUTION:
				double semDist = SemanticDistance.calculate(inputWord.getText(), graphWord.getText());
				if (semDist > 0) {
					return 2 * semDist;
				}
				else {
					return MIN_COST_OF_S_RECORD;
				}
			default:
				throw new IllegalArgumentException("Invalid type of operator.");
		}
	}

	public Operator getOperator() {
		return operator;
	}

	public Word getGraphWord() {
		return graphWord;
	}

	public Word getInputWord() {
		return inputWord;
	}

	public double getCost() {
		return cost;
	}

	@Override
	public String toString() {
		return "Record(" + operator + ", " + String.valueOf(graphWord) + ", " + String.valueOf(inputWord) + ")";
	}
	
	public Record clone() {
		Record r = new Record();
		r.operator = operator;
		r.graphWord = graphWord;
		r.inputWord = inputWord;
		r.cost = cost;
		return r;
	}
}
